package com.atguigu.java3;

import com.atguigu.java2.Employee;
import com.atguigu.java2.EmployeeData;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author : leimingchao
 * @Description:
 *      测试Stream的中间操作
 *
 * @date Date : 2021年06月19日 13:19
 */
public class StreamAPITest2 {

    /**
     * 1.筛选与切片
     *
     *     filter(Predicate p) 接收 Lambda ， 从流中排除某些元素
     *
     *     distinct() 筛选，通过流所生成元素的 hashCode() 和 equals() 去除重复元素
     *
     *     limit(long maxSize) 截断流，使其元素不超过给定数量
     *
     *     skip(long n) 跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，则返回一个空流。与 limit(n) 互补
     *
     *
     */
    @Test
    public void test() {
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Employee> stream = employees.stream();

        //查询员工表中薪资大于7000的员工信息
        stream.filter(employee -> employee.getSalary() >7000).forEach(System.out::println);
        System.out.println();

        employees.stream().limit(3).forEach(System.out::println);

        System.out.println();
        employees.stream().skip(30).forEach(System.out::println);

        employees.add(new Employee(1010,"刘强东",40,8000));
        employees.add(new Employee(1010,"刘强东",40,8000));
        employees.add(new Employee(1010,"刘强东",40,8000));
        employees.add(new Employee(1010,"刘强东",40,8000));
        employees.add(new Employee(1010,"刘强东",40,8000));
        employees.add(new Employee(1010,"刘强东",40,8000));

        System.out.println(employees);
        System.out.println();
        employees.stream().distinct().forEach(System.out::println);

    }

    /**
     * 2-映 射
     *      map(Function f)
     *              接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。
     *
     *      mapToDouble(ToDoubleFunction f):
     *              接收一个函数作为参数，该函数会被应用到每个元素上，产生一个新的 DoubleStream。
     *
     *      mapToInt(ToIntFunction f)
     *              接收一个函数作为参数，该函数会被应用到每个元素上，产生一个新的 IntStream。
     *
     *      mapToLong(ToLongFunction f)
     *              接收一个函数作为参数，该函数会被应用到每个元素上，产生一个新的 LongStream。
     *
     *      flatMap(Function f)
     *              接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流
     *
     */

    @Test
    public void test2() {
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        list.stream().map(str ->str.toUpperCase()).forEach(System.out::println);
        System.out.println("*************************************************");
        list.stream().map(String::toUpperCase).forEach(System.out::println);
        System.out.println("*************************************************");
        //练习1：获取员工姓名大于3的员工的姓名
        EmployeeData.getEmployees()
                .stream()
                .filter(employee -> employee.getName().length() >3)
                .map(Employee::getName)
                .forEach(System.out::println);
        System.out.println("************************************************");
        //练习2：
        Stream<Stream<Character>> streamStream = list.stream().map(StreamAPITest2::fromString2Stream);
        streamStream.forEach(s ->s.forEach(System.out::println));
        System.out.println("**********************************");
        Stream<Character> characterStream = list.stream().flatMap(StreamAPITest2::fromString2Stream);
        characterStream.forEach(System.out::println);
    }

    /** 3-排序
     *        sorted() 产生一个新流，其中按自然顺序排序
     *
     *        sorted(Comparator com) 产生一个新流，其中按比较器顺序排序
     */
    @Test
    public void test4() {
        List<Integer> integers = Arrays.asList(12, 43, 65, 34, 87, 0, -98, 7);
        integers.stream().sorted().forEach(System.out::println);
        System.out.println("*********************************");
        //抛异常，原因：Employee类没有实现Comparable接口
        // EmployeeData.getEmployees().stream().sorted().forEach(System.out::println);

        EmployeeData.getEmployees().stream().sorted((e1,e2) ->Integer.compare(e1.getAge(),e2.getAge())).forEach(System.out::println);
        System.out.println("****************************");
        EmployeeData.getEmployees().stream().sorted(Comparator.comparingInt(Employee::getAge)).forEach(System.out::println);
        System.out.println("******************************************");
        EmployeeData.getEmployees().stream().sorted((e1,e2) ->{
            int ageValue = Integer.compare(e1.getAge(), e2.getAge());
            if (ageValue != 0) {
                return ageValue;
            } else {
                return - Double.compare(e1.getSalary(), e2.getSalary());
            }
        }).forEach(System.out::println);
    }

    /**
     * 将字符串中的多个字符构成的集合转换为对应的Stream的实例
     * @param str
     * @return
     */
    public static Stream<Character> fromString2Stream(String str) {
        List<Character> list = new ArrayList<>();
        for (Character c : str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }

    @Test
    public void test3() {
        List list1 = new ArrayList();
        list1.add(1);
        list1.add(2);
        list1.add(3);

        List list2 = new ArrayList();
        list2.add(1);
        list2.add(2);
        list2.add(3);
        // list1.add(list2);
        list1.addAll(list2);
        System.out.println(list1);
    }
}
